package FrontEnd;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.URL;
import Errors.*;
import Renderer.*;

/*******************************************************************************
 * Class representing the user interface of the browser.
 * @author Tudor Pascu
 * @version FINAL
 *******************************************************************************/
public class GUI
{
    private JPanel page = new JPanel();
    private HTMLRenderer renderer;
    private ErrorLog errors;
    private JTextField linkBar;//Text field containing file address.
    private JFrame frame;//Main frame.
    private JFrame errorLogFrame;//Error log frame.
    private boolean errorsStarted = false;//True if error log is open.
    private JScrollPane scrollPane;//ScrollPane containing the HTML page.
    private boolean initialised = false;
    //GUI COLOURS:
    private Color lightGrey = new Color(197,206,213);
    private Color darkBlue = new Color(29,73,134);
    private Color deepRed = new Color(173,0,11);

    /***************************************************************************
     * Starts the browser.
     ***************************************************************************/
    public static void main(String[] args)
    {
        if(args.length > 0)
        {
            new GUI(args[0]);
        } else {
            new GUI();
        }
    }

    /***************************************************************************
     * Constructor for user interface.
     ***************************************************************************/
    public GUI()
    {
        page.setLayout(null);
        errors = new ErrorLog();
        drawWindow();
        renderer = new HTMLRenderer(page, errors, this);
        update();
        initialised = true;
    }

    /***************************************************************************
     * Constructor for user interface.
     * @param file Address of the page to be loaded.
     ***************************************************************************/
    public GUI(String file)
    {
        page.setLayout(null);
        errors = new ErrorLog();
        drawWindow();
        renderer = new HTMLRenderer(page, file, errors, this);
        update();
        initialised = true;
    }

    /***************************************************************************
     * Creates the GUI window.
     ***************************************************************************/
    public void drawWindow()
    {
        ////////////////////////
        // CREATES THE HEADER //
        ////////////////////////
        JPanel header = new JPanel(new BorderLayout());
        header.setBackground(lightGrey);
        JPanel buttons = new JPanel(new GridLayout(1,5));
        buttons.setBackground(lightGrey);

        //BACK BUTTON:
        URL backButtonURL = getClass().getResource("back.jpg");
        ImageIcon backButtonIcon = new ImageIcon(backButtonURL);
        JLabel backButton = new JLabel(backButtonIcon);
        backButton.addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent evt)
            {
                renderer.getPreviousPage();
                update();
            }
        });
        buttons.add(backButton);

        //FORWARD BUTTON:
        URL forwardButtonURL = getClass().getResource("forward.jpg");
        ImageIcon forwardButtonIcon = new ImageIcon(forwardButtonURL);
        JLabel forwardButton = new JLabel(forwardButtonIcon);
        forwardButton.addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent evt)
            {
                renderer.getNextPage();
                update();
            }
        });
        buttons.add(forwardButton);

        //ZOOM IN BUTTON:
        URL zoomInURL = getClass().getResource("zoom_in.jpg");
        ImageIcon zoomInIcon = new ImageIcon(zoomInURL);
        JLabel zoomInButton = new JLabel(zoomInIcon);
        zoomInButton.addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent evt)
            {
                renderer.zoomIn();
                update();
            }
        });
        buttons.add(zoomInButton);

        //ZOOM OUT BUTTON:
        URL zoomOutURL = getClass().getResource("zoom_out.jpg");
        ImageIcon zoomOutIcon = new ImageIcon(zoomOutURL);
        JLabel zoomOutButton = new JLabel(zoomOutIcon);
        zoomOutButton.addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent evt)
            {
                renderer.zoomOut();
                update();
            }
        });
        buttons.add(zoomOutButton);

        //HOME BUTTON:
        URL homeButtonURL = getClass().getResource("home.jpg");
        ImageIcon homeButtonIcon = new ImageIcon(homeButtonURL);
        JLabel homeButton = new JLabel(homeButtonIcon);
        homeButton.addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent evt)
            {
                renderer.loadMainPage();
                update();
            }
        });
        buttons.add(homeButton);
        header.add(buttons, "West");
        JPanel linkPanel = new JPanel(new BorderLayout());

        //LINK TEXTFIELD:
        linkBar = new JTextField();
        linkPanel.add(linkBar, "Center");

        //GO BUTTON:
        URL goButtonURL = getClass().getResource("go.jpg");
        ImageIcon goButtonIcon = new ImageIcon(goButtonURL);
        JLabel goButton = new JLabel(goButtonIcon);
        goButton.addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent evt)
            {
                renderer.loadLinkedPage(linkBar.getText());
                update();
            }
        });
        linkPanel.add(goButton, "East");
        header.add(linkPanel, "Center");

        /////////////////////////////////////////////////
        // CREATES THE SCROLL PANE CONTAINING THE PAGE //
        /////////////////////////////////////////////////
        page.setBackground(Color.white);
        scrollPane = new JScrollPane(page);
        scrollPane.setBackground(lightGrey);
        scrollPane.setLayout(new ScrollPaneLayout());

        ////////////////////////
        // CREATES THE FOOTER //
        ////////////////////////
        JPanel footer = new JPanel(new BorderLayout());
        footer.setBackground(lightGrey);
        JLabel copyRight = new JLabel("© Browser By Group 2.");
        copyRight.setForeground(darkBlue);
        footer.add(copyRight, "West");
        URL errorLogButtonURL = getClass().getResource("error_log.jpg");
        ImageIcon errorLogButtonIcon = new ImageIcon(errorLogButtonURL);
        JLabel errorLogButton = new JLabel(errorLogButtonIcon);
        errorLogButton.addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent evt)
            {
                displayErrors();
            }
        });
        footer.add(errorLogButton, "East");

        //////////////////////
        // FRAME PROPERTIES //
        //////////////////////
        frame = new JFrame("Browser By Group 2");
        frame.setLayout(new BorderLayout());
        frame.add(header, "North");
        frame.add(scrollPane, "Center");
        frame.add(footer, "South");
        frame.setBackground(lightGrey);
        frame.setSize(1024, 768);
        frame.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.addComponentListener(new ComponentListener()
        {
            public void componentResized(ComponentEvent e)
            {
                if(initialised)
                {
                    renderer.loadLinkedPage(renderer.getCurrentPage());
                    update();
                }
            }
            public void componentMoved(ComponentEvent e) {}
            public void componentShown(ComponentEvent e) {}
            public void componentHidden(ComponentEvent e) {}
        });
    }

    /***************************************************************************
     * Sets the title of the window.
     * @param title Title of the window.
     ***************************************************************************/
    public void setTitle(String title)
    {
        frame.setTitle(title + " - Browser By Group 2");
    }

    /***************************************************************************
     * Refreshes the GUI.
     ***************************************************************************/
    public void update(){
        errors.outputErrors();
        linkBar.setText(renderer.getCurrentPage());
        page.setPreferredSize(new Dimension(renderer.getMaxX(), renderer.getMaxY()));
        page.setBackground(Color.white);
        frame.remove(scrollPane);
        scrollPane = new JScrollPane(page);
        scrollPane.setBackground(lightGrey);
        JScrollBar horizontal = new JScrollBar();
        JScrollBar vertical = new JScrollBar();
        horizontal.setOrientation(JScrollBar.HORIZONTAL);
        vertical.setOrientation(JScrollBar.VERTICAL);
        scrollPane.setHorizontalScrollBar(horizontal);
        scrollPane.setVerticalScrollBar(vertical);
        frame.add(scrollPane, "Center");
        frame.setVisible(true);
    }

    /***************************************************************************
     * Creates a new JPanel and returns it.
     * @return New JPanel.
     ***************************************************************************/
    public JPanel getFreshPage()
    {
        page = new JPanel();
        page.setLayout(null);
        return page;
    }

    /***************************************************************************
     * Gets the width of the scrollPane's window.
     * @return Page width.
     ***************************************************************************/
    public int getPageWidth()
    {
        return scrollPane.getWidth();
    }

    /***************************************************************************
     * Displays the errors.
     ***************************************************************************/
    public void displayErrors(){
        if(errors.hasError()){
            if(errorsStarted)errorLogFrame.dispose();
            errorLogFrame = new JFrame("Error Log");
            errorLogFrame.setLayout(new BorderLayout());
            JPanel errorList = new JPanel(new GridLayout(((errors.getErrors().size()) + 1), 1));
            errorList.setBackground(lightGrey);
            JLabel title = new JLabel("ERROR LIST:");
            title.setForeground(darkBlue);
            errorList.add(title);
            //Adds the errors to the JPanel list.
            for(int i = 0; i < errors.getErrors().size(); i++){
                JLabel temp = new JLabel(" > " + errors.getErrors().get(i));
                temp.setForeground(deepRed);
                temp.setBackground(lightGrey);
                errorList.add(temp);
            }

            //Moves the error list to the top of the page.
            JPanel moveUp = new JPanel(new BorderLayout());
            moveUp.add(errorList, "North");
            moveUp.setBackground(lightGrey);

            //Creates a JScrollPane that will contain the list of errors.
            JScrollPane newScrollPane = new JScrollPane(moveUp);
            errorLogFrame.add(newScrollPane);
            errorLogFrame.setBackground(lightGrey);
            errorLogFrame.setSize(640, 320);
            errorLogFrame.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
            errorLogFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            errorLogFrame.setVisible(true);
            errorLogFrame.setResizable(false);
            errorsStarted = true;
        } else {
            //Creates a JScrollPane that will "NO ERRORS FOUND".
            if(errorsStarted) errorLogFrame.dispose();
            errorLogFrame = new JFrame("Error Log");
            errorLogFrame.setLayout(new BorderLayout());
            JPanel errorPanel = new JPanel();
            errorPanel.setBackground(lightGrey);
            JLabel noErrorsLabel = new JLabel("NO ERRORS FOUND.");
            noErrorsLabel.setForeground(darkBlue);
            errorPanel.add(noErrorsLabel);
            errorLogFrame.add(errorPanel, "Center");
            errorLogFrame.setSize(640, 60);
            errorLogFrame.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
            errorLogFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            errorLogFrame.setVisible(true);
            errorLogFrame.setResizable(false);
            errorsStarted = true;
        }
    }
}